﻿Imports System.Collections.Generic
Imports System.IO
Imports System.Windows.Forms
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

''' <summary>
''' 这个类用于处理无需保存到硬盘功能的辅助层管理器
''' </summary>
''' <remarks></remarks>


<Serializable()> Public Class ReadOnlyLayerManager
    '内部的关键字段
    <NonSerialized()> Dim mapwin As AxMapWinGIS.AxMap
    Dim m_LayerDic As New Dictionary(Of String, Layer)

    Dim appProjectPath As String
    Dim DllsubPath As String = "\GisFile\"


    '关于鼠标移动
    Dim mux As Double
    Dim muy As Double


    '工具方法，在工具方法不是很多的时候，先单独写
    Dim moveTool As LineTool
    'Dim moveTool As LineTool
    Dim bUseMoveTool As Boolean = False


    '构造方法
    Public Sub New(ByRef win As AxMapWinGIS.AxMap)
        mapwin = win

        mapwin.SendMouseDown = True
        mapwin.SendMouseMove = True
        mapwin.SendMouseMove = True
        mapwin.SendMouseUp = True
        mapwin.SendSelectBoxFinal = True


        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmNone

      



        '工具方法辅助的地方
        moveTool = New LineTool
        AddHandler moveTool.endDrawing, AddressOf Me.OnmToolDrawingEnd
        moveTool.SetMapRef(mapwin)





        '为了解决刷新问题，实行分发消息制度,一次订阅，四处分发
        AddHandler mapwin.MouseDownEvent, AddressOf Me.mapMain_MouseDownEvent

        AddHandler mapwin.MouseUpEvent, AddressOf Me.mapMain_MouseUpEvent
        AddHandler mapwin.DblClick, AddressOf Me.mapMain_DblClick

        AddHandler mapwin.PreviewKeyDown, AddressOf Me.mapMain_PreviewKeyDown

        AddHandler mapwin.SelectBoxFinal, AddressOf Me.mapMain_SelectBoxFinal

        AddHandler mapwin.ExtentsChanged, AddressOf Me.OnExtentsChanged

        AddHandler mapwin.MouseMoveEvent, AddressOf Me.mapMain_MouseMoveEvent



    End Sub

    Public Sub ChangeProjPath(ByVal strPath As String)

        appProjectPath = strPath + DllsubPath
        Dim haveImages As Boolean = Directory.Exists(appProjectPath)
        If (Not haveImages) Then
            Directory.CreateDirectory(appProjectPath)
        End If

        Me.UnloadAllLayer()



    End Sub


    '对外暴露一些事件，比如mouse的位置
    Public Event mousePosChanged(ByVal x As Double, ByVal y As Double)


    '提供更多可供外部调用的事件

    Public Event LayerAdded(ByVal ln As String, ByVal desc As String)
    Public Event LayerRemoved(ByVal ln As String)
    Public Event LayerDescChanged(ByVal ln As String, ByVal ds As String)


    '消息分发函数
    Public Sub mapMain_MouseDownEvent(ByVal sender As System.Object, ByVal e As AxMapWinGIS._DMapEvents_MouseDownEvent)

        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.mapMain_MouseDownEvent(sender, e)
        Next



        If bUseMoveTool And e.button = 1 Then

            moveTool.mouseDown(sender, e)
            'mapwin.NewDrawing(MapWinGIS.tkDrawReferenceList.dlSpatiallyReferencedList)
            'Dim tx, ty As Double
            'mapwin.PixelToProj(e.x, e.y, tx, ty)
            'mapwin.DrawCircle(tx, ty, 4, 600, True)


        End If

    End Sub
    Public Sub mapMain_MouseMoveEvent(ByVal sender As System.Object, ByVal e As AxMapWinGIS._DMapEvents_MouseMoveEvent)

        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.mapMain_MouseMoveEvent(sender, e)
        Next




        If bUseMoveTool And e.button = 1 Then

            moveTool.mouseMove(sender, e)


        End If




        mapwin.PixelToProj(e.x, e.y, mux, muy)
        RaiseEvent mousePosChanged(mux, muy)

    End Sub

    Public Sub mapMain_MouseUpEvent(ByVal sender As System.Object, ByVal e As AxMapWinGIS._DMapEvents_MouseUpEvent)
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.mapMain_MouseUpEvent(sender, e)
        Next

        If bUseMoveTool And e.button = 1 Then

            moveTool.mouseUp(sender, e)
        End If

    End Sub
    Public Sub mapMain_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs)

        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.mapMain_PreviewKeyDown(sender, e)
        Next

    End Sub
    Public Sub mapMain_DblClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.mapMain_DblClick(sender, e)
        Next
    End Sub

    Public Sub mapMain_SelectBoxFinal(ByVal sender As System.Object, ByVal e As AxMapWinGIS._DMapEvents_SelectBoxFinalEvent)
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.mapMain_SelectBoxFinal(sender, e)
        Next
    End Sub
    Public Sub OnExtentsChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.OnExtentsChanged(sender, e)
        Next

    End Sub



    '经再设计的主体功能函数
    Public Sub AddLayer(ByVal lay As Layer)
        If m_LayerDic.ContainsKey(lay.LnameProperty) Then
            MessageBox.Show("该层的名称ID已经存在！" + lay.LnameProperty)
            Return
        End If


        AddHandler lay.DescChanged, AddressOf Me.OndescChanged
        '根据类的类型不同，做一些不同的处理
        If lay.IsEditable Then

            Dim elay As EditableShapeLayer = lay
            AddHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd
            AddHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
            AddHandler elay.EntitySelected, AddressOf Me.OnSelected
            AddHandler elay.AskForMove, AddressOf Me.OnAskMove



        End If



        '首先是文件创建逻辑




        lay.InitNewLayer(mapwin, appProjectPath)

        m_LayerDic.Add(lay.LnameProperty, lay)



        RaiseEvent LayerAdded(lay.LnameProperty, lay.LdescProperty)


    End Sub

    Public Sub LoadLayer(ByVal lay As Layer, ByVal strName As String)
        If m_LayerDic.ContainsKey(lay.LnameProperty) Then
            MessageBox.Show("该层的名称ID已经存在！" + lay.LnameProperty)
            Return
        End If



        AddHandler lay.DescChanged, AddressOf Me.OndescChanged
        '根据类的类型不同，做一些不同的处理
        If lay.IsEditable Then

            Dim elay As EditableShapeLayer = lay
            AddHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd
            AddHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
            AddHandler elay.EntitySelected, AddressOf Me.OnSelected
            AddHandler elay.AskForMove, AddressOf Me.OnAskMove



        End If

        lay.FnameProperty = strName

        lay.InitLayer(mapwin)

        m_LayerDic.Add(lay.LnameProperty, lay)

    End Sub
    ''' <summary>
    ''' 加载并添加一个已经在本项目文件夹保存的单一图层
    ''' </summary>
    ''' <param name="ln"></param>
    ''' <remarks></remarks>
    Public Function LoadSingleLayer(ByVal ln As String) As Boolean

        Dim myfilename As String = appProjectPath + ln + ".fgis"


        If Not System.IO.File.Exists(myfilename) Then

            MessageBox.Show("加载文件失败！未找到存储的文件！" + myfilename.ToString())
            Return False

        End If

        Dim formatter As IFormatter = New BinaryFormatter()

        Dim stream As Stream = New FileStream(myfilename, FileMode.Open, FileAccess.Read, FileShare.None)


        Dim lay As Layer


        lay = formatter.Deserialize(stream)

        stream.Close()




        '对变量重新赋值


        lay.ReLoad(mapwin, appProjectPath)

        AddHandler lay.DescChanged, AddressOf Me.OndescChanged
        If lay.IsEditable Then

            Dim elay As EditableShapeLayer = lay

            AddHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd

            AddHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
            AddHandler elay.EntitySelected, AddressOf Me.OnSelected

            AddHandler elay.AskForMove, AddressOf Me.OnAskMove

        End If

        RaiseEvent LayerAdded(ln, lay.LdescProperty)



        Me.SetMNormal()

        Return True


    End Function

    ''' <summary>
    ''' 将一个单一图层保存到项目文件，以方便日后加载
    ''' </summary>
    ''' <param name="ln"></param>
    ''' <remarks></remarks>
    Public Sub SaveSingleLayer(ByVal ln As String)

        Dim myfilename As String = appProjectPath + ln + ".fgis"



        Dim lay As Layer
        Me.GetLayer(ln, lay)

        If lay Is Nothing Then

            MessageBox.Show("未发现对应ID的图层")
            Return

        End If

        '文件的删除逻辑

        If File.Exists(myfilename) Then
            Try
                File.SetAttributes(myfilename, FileAttributes.Normal)
                File.Delete(myfilename)

            Catch ex As Exception

                MessageBox.Show("删除旧文件失败 ！ " + myfilename + "  " + ex.Message)
            End Try



        End If


        Dim formatter As New BinaryFormatter()
        Dim stream As Stream = New FileStream(myfilename, FileMode.Create, FileAccess.Write, FileShare.None)


        formatter.Serialize(stream, lay)
        stream.Close()

        '对外部文件进行保存

        lay.Save()


    End Sub

    Public Sub RemoveLayer(ByVal ln As String)
        Dim lay As Layer
        Me.GetLayer(ln, lay)

        If lay Is Nothing Then
            Return
        End If

        If lay.IsEditable Then

            Dim elay As EditableShapeLayer = lay
            RemoveHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd

            RemoveHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
            RemoveHandler elay.EntitySelected, AddressOf Me.OnSelected

            RemoveHandler elay.AskForMove, AddressOf Me.OnAskMove

        End If


        If lay IsNot Nothing Then

            lay.Dispose()
            mapwin.RemoveLayer(lay.m_iLayer)
            'lay = Nothing

        End If

        Dim strLname As String = lay.LnameProperty

        If m_LayerDic.ContainsKey(lay.LnameProperty) Then
            m_LayerDic.Remove(ln)

        End If


        RaiseEvent LayerRemoved(strLname)

    End Sub
    Public Sub GetLayer(ByVal ln As String, ByRef lay As Layer)

        '注意这里是引用传递
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic
            If kv.Key = ln Then

                lay = kv.Value

                Return


            End If

        Next

    End Sub

    Public Sub SetAllLayerNoEdditable()
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic
            kv.Value.SetNoEdditing()
        Next
        mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault

        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmNone


        '哈哈，干掉他
        bUseMoveTool = False



    End Sub

    Public Sub SetMSelect()

        Me.SetAllLayerNoEdditable()

        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmSelection

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault



    End Sub

    Public Sub SetMSelect(ByRef cur As Cursor)
        Me.SetAllLayerNoEdditable()

        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmSelection

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrUserDefined
        mapwin.UDCursorHandle = cur.Handle


    End Sub

    Public Sub SetMHand()
        Me.SetAllLayerNoEdditable()

        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmPan
        mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault




    End Sub

    Public Sub SetMHand(ByRef cur As Cursor)
        Me.SetAllLayerNoEdditable()

        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmPan


        mapwin.MapCursor = MapWinGIS.tkCursor.crsrUserDefined
        mapwin.UDCursorHandle = cur.Handle




    End Sub

    Public Sub SetMNormal()
        Me.SetAllLayerNoEdditable()


        mapwin.Redraw()




    End Sub

    Public Sub SetMZoomIn()


        Me.SetAllLayerNoEdditable()
        mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault
        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmZoomIn

    End Sub

    Public Sub SetMZoomIn(ByRef cur As Cursor)
        Me.SetAllLayerNoEdditable()
        'mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault
        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmZoomIn

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrUserDefined
        mapwin.UDCursorHandle = cur.Handle

    End Sub


    Public Sub SetMZoomOut()

        Me.SetAllLayerNoEdditable()

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault
        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmZoomOut






    End Sub

    Public Sub SetMZoomOut(ByRef cur As Cursor)
        Me.SetAllLayerNoEdditable()


        mapwin.CursorMode = MapWinGIS.tkCursorMode.cmZoomOut

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrUserDefined
        mapwin.UDCursorHandle = cur.Handle

    End Sub

    Public Sub SetToExtent()
        mapwin.MapCursor = MapWinGIS.tkCursor.crsrMapDefault

        Me.SetAllLayerNoEdditable()

        mapwin.ZoomToMaxExtents()

    End Sub

    Public Sub SetZoomToLayer(ByVal ln As String)

        Dim lay As Layer
        Me.GetLayer(ln, lay)


        If lay IsNot Nothing Then

            mapwin.ZoomToLayer(lay.m_iLayer)

        End If


    End Sub


    Public Function MoveLayerPosition(ByVal initPos As Integer, ByVal targPos As Integer) As Boolean

        Dim b As Boolean = False
        b = mapwin.MoveLayer(initPos, targPos)

        Return b
        'If Not b Then
        '    MessageBox.Show("调试，层移动失败！")

        'End If



    End Function
    Public Sub MoveLayerTop(ByVal initPos As Integer)
        mapwin.MoveLayerTop(initPos)
    End Sub
    Public Sub MoveLayerBottom(ByVal initPos As Integer)
        mapwin.MoveLayerBottom(initPos)
    End Sub

    Public Sub MoveLayerUp(ByVal initPos As Integer)
        mapwin.MoveLayerUp(initPos)

    End Sub

    Public Sub MoveLayerDown(ByVal initPos As Integer)
        mapwin.MoveLayerDown(initPos)
    End Sub

    Public Function GetPosFromLName(ByVal ln As String) As Integer

        Dim iPos As Integer = -1
        If m_LayerDic.ContainsKey(ln) Then

            iPos = m_LayerDic.Item(ln).GetLayerPos()
        End If

        Return iPos

    End Function



    '经再设计的辅助功能函数
    Public Function getLayerHandle(ByVal ln As String) As Integer
        If mapwin.NumLayers > 0 Then

            For i As Integer = 0 To mapwin.NumLayers - 1

                Dim iLayer As Integer = mapwin.get_LayerHandle(i)
                If mapwin.get_LayerKey(iLayer) = ln Then

                    Return iLayer

                End If


            Next




        End If

        Return -1


    End Function
    Public Function getUIntFromGDIColor(ByVal clr As Drawing.Color) As UInt32

        Return RGB(clr.R, clr.G, clr.B)

    End Function

    '关于模块形式的加载与保存

    Public Sub Save(ByVal projName As String)


        Dim myfilename As String = appProjectPath + projName + ".fgis"


        '取类的副本,然后清空外部引用的事件
        Dim tempDic As New Dictionary(Of String, Layer)


        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic



            tempDic.Add(kv.Key, kv.Value)


        Next

        'For Each kv As KeyValuePair(Of String, Layer) In tempDic

        '    If kv.Value.IsEditable Then

        '        Dim elay As EditableShapeLayer = kv.Value

        '        RemoveHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd

        '        RemoveHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
        '        RemoveHandler elay.EntitySelected, AddressOf Me.OnSelected

        '        RemoveHandler elay.AskForMove, AddressOf Me.OnAskMove


        '    End If

        'Next


        '文件的删除逻辑

        If File.Exists(myfilename) Then
            Try
                File.SetAttributes(myfilename, FileAttributes.Normal)
                File.Delete(myfilename)

            Catch ex As Exception

                MessageBox.Show("删除旧文件失败 ！ " + myfilename + "  " + ex.Message)
            End Try



        End If


        Dim formatter As New BinaryFormatter()
        Dim stream As Stream = New FileStream(myfilename, FileMode.Create, FileAccess.Write, FileShare.None)


        formatter.Serialize(stream, m_LayerDic)
        stream.Close()

        '对外部文件进行保存
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.Save()

        Next

    End Sub
    Public Sub SaveAs(ByVal svPath As String, ByVal projName As String)


        Dim myfilename As String = svPath + DllsubPath + projName + ".fgis"
        Dim myfilepath As String = svPath + DllsubPath

        If Not Directory.Exists(svPath + DllsubPath) Then

            Directory.CreateDirectory(svPath + DllsubPath)

        End If


        '取类的副本,然后清空外部引用的事件
        Dim tempDic As New Dictionary(Of String, Layer)


        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            tempDic.Add(kv.Key, kv.Value)


        Next

        'For Each kv As KeyValuePair(Of String, Layer) In tempDic

        '    If kv.Value.IsEditable Then

        '        Dim elay As EditableShapeLayer = kv.Value

        '        RemoveHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd

        '        RemoveHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
        '        RemoveHandler elay.EntitySelected, AddressOf Me.OnSelected

        '        RemoveHandler elay.AskForMove, AddressOf Me.OnAskMove

        '    End If

        'Next


        '文件的删除逻辑

        If File.Exists(myfilename) Then
            Try
                File.SetAttributes(myfilename, FileAttributes.Normal)
                File.Delete(myfilename)

            Catch ex As Exception

                MessageBox.Show("删除旧文件失败 ！ " + myfilename + "  " + ex.Message)
            End Try



        End If



        Dim formatter As New BinaryFormatter()
        Dim stream As Stream = New FileStream(myfilename, FileMode.Create, FileAccess.Write, FileShare.None)


        formatter.Serialize(stream, tempDic)
        stream.Close()


        '对外部文件进行保存
        For Each kv As KeyValuePair(Of String, Layer) In tempDic

            kv.Value.SaveAs(myfilepath)

        Next

        '发现一个奇怪的现象，那就是另存为后，图像的文件也跟着走了



    End Sub

    Public Sub Load(ByVal svPath As String, ByVal projName As String)

        '清空原有选项
        Me.UnloadAllLayer()

        '对全局变量赋值
        appProjectPath = svPath + DllsubPath


        '执行加载过程
        Dim myfilename As String = appProjectPath + projName + ".fgis"


        If Not System.IO.File.Exists(myfilename) Then

            MessageBox.Show("加载文件失败！未找到存储的文件！" + myfilename.ToString())
            Return

        End If

        Dim formatter As IFormatter = New BinaryFormatter()

        Dim stream As Stream = New FileStream(myfilename, FileMode.Open, FileAccess.Read, FileShare.None)


        m_LayerDic = formatter.Deserialize(stream)

        stream.Close()

        '对变量重新赋值
        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            kv.Value.ReLoad(mapwin, appProjectPath)

            AddHandler kv.Value.DescChanged, AddressOf Me.OndescChanged
            If kv.Value.IsEditable Then

                Dim elay As EditableShapeLayer = kv.Value

                AddHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd

                AddHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
                AddHandler elay.EntitySelected, AddressOf Me.OnSelected

                AddHandler elay.AskForMove, AddressOf Me.OnAskMove

            End If

            RaiseEvent LayerAdded(kv.Key, kv.Value.LdescProperty)
        Next


        Me.SetMNormal()


    End Sub

    Public Sub UnloadAllLayer()


        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            RemoveHandler kv.Value.DescChanged, AddressOf Me.OndescChanged
            If kv.Value.IsEditable Then

                Dim elay As EditableShapeLayer = kv.Value

                RemoveHandler elay.AskForAddEntity, AddressOf Me.OnAskAdd

                RemoveHandler elay.AskForRemoveEntity, AddressOf Me.OnAskRemove
                RemoveHandler elay.EntitySelected, AddressOf Me.OnSelected

                RemoveHandler elay.AskForMove, AddressOf Me.OnAskMove


            End If


            RaiseEvent LayerRemoved(kv.Key)

            kv.Value.Dispose()

        Next

        m_LayerDic.Clear()
        mapwin.RemoveAllLayers()

    End Sub


    '公用的事件模型

    Public Event AskForAddEntity(ByVal ln As String, ByVal ptlist() As MapWinGIS.Point, ByVal shpDesc As String)
    Public Event AskForRemoveEntity(ByVal ln As String, ByVal sn As String)
    Public Event EntitySelected(ByVal ln As String, ByVal sn As String)
    Public Event AskForMove(ByVal ln As String, ByVal sn As String(), ByVal mxx As Double, ByVal myy As Double)


    Private Sub OndescChanged(ByVal ln As String, ByVal ds As String)

        RaiseEvent LayerDescChanged(ln, ds)
    End Sub

    Private Sub OnAskAdd(ByVal ln As String, ByVal pt As MapWinGIS.Point(), ByVal shpDesc As String)

        RaiseEvent AskForAddEntity(ln, pt, shpDesc)

    End Sub

    Private Sub OnAskRemove(ByVal ln As String, ByVal sn As String)


        RaiseEvent AskForRemoveEntity(ln, sn)



    End Sub

    Private Sub OnSelected(ByVal ln As String, ByVal sn As String)

        RaiseEvent EntitySelected(ln, sn)

    End Sub

    Private Sub OnAskMove(ByVal ln As String, ByVal sn As String(), ByVal mxx As Double, ByVal myy As Double)
        RaiseEvent AskForMove(ln, sn, mxx, myy)

    End Sub

    Public Sub UseMoveTool(ByVal b As Boolean)
        If b Then
            Me.SetAllLayerNoEdditable()
        End If

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrSizeAll

        bUseMoveTool = b

    End Sub

    Public Sub UseMoveTool(ByVal b As Boolean, ByVal cur As Cursor)
        If b Then
            Me.SetAllLayerNoEdditable()
        End If

        'mapwin.MapCursor = MapWinGIS.tkCursor.crsrSizeAll

        mapwin.MapCursor = MapWinGIS.tkCursor.crsrUserDefined
        mapwin.UDCursorHandle = cur.Handle

        bUseMoveTool = b

    End Sub


    Private Sub OnmToolDrawingEnd(ByVal d As Double)

        If Not bUseMoveTool Then

            Return
        End If

        Dim xOff, yOff As Double


        yOff = moveTool.mx
        xOff = moveTool.my

        For Each pair As KeyValuePair(Of String, Layer) In m_LayerDic

            If pair.Value.IsEditable Then

                Dim elay As EditableShapeLayer = pair.Value

                elay.AskMoveSelShapes(xOff, yOff)


            End If

        Next


    End Sub

    Public Function GetSelectedShapeNames() As List(Of String)

        Dim selList As New List(Of String)
        For Each pair As KeyValuePair(Of String, Layer) In m_LayerDic

            If pair.Value.IsEditable Then

                Dim elay As EditableShapeLayer = pair.Value



                selList.AddRange(elay.GetSelectedShapes())




            End If

        Next

        Return selList

    End Function


    Public Sub CopyImageToClipboard()

        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot(mapwin.Extents), MapWinGIS.Image)

        If image Is Nothing Then
            Return
        End If

        Dim cvter As New MapWinUtility.ImageUtils
        Clipboard.SetDataObject(cvter.IPictureDispToImage(CType(mapwin.SnapShot(mapwin.Extents), MapWinGIS.Image).Picture))

    End Sub


    ''' <summary>
    ''' 指定参数输出图像
    ''' </summary>
    ''' <param name="left"></param>
    ''' <param name="right"></param>
    ''' <param name="top"></param>
    ''' <param name="bottom"></param>
    ''' <param name="imgWidth">图像宽度</param>
    ''' <remarks></remarks>
    Public Sub CopyImageToClipboardByParam(ByVal left As Double, ByVal right As Double, ByVal top As Double, ByVal bottom As Double, ByVal imgWidth As Integer)



        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot3(left, right, top, bottom, imgWidth), MapWinGIS.Image)

        If image Is Nothing Then
            Return
        End If

        Dim cvter As New MapWinUtility.ImageUtils
        Clipboard.SetDataObject(cvter.IPictureDispToImage(CType(mapwin.SnapShot3(left, right, top, bottom, imgWidth), MapWinGIS.Image).Picture))

    End Sub

    ''' <summary>
    ''' 这里根据指定图层的大小来计算图的大小
    ''' </summary>
    ''' <param name="iHandle"></param>
    ''' <param name="zoom"></param>
    ''' <param name="imgWidth"></param>
    ''' <remarks></remarks>
    Public Sub CopyImageToClipboardByLayerExtent(ByVal iHandle As Integer, ByVal zoom As Double, ByVal imgWidth As Integer)


        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot2(iHandle, zoom, imgWidth), MapWinGIS.Image)

        If image Is Nothing Then
            Return
        End If


        Dim cvter As New MapWinUtility.ImageUtils


        Clipboard.SetDataObject(cvter.IPictureDispToImage(CType(mapwin.SnapShot2(iHandle, zoom, imgWidth), MapWinGIS.Image).Picture))


    End Sub

    Public Function SaveImageFile(ByVal fName As String) As Boolean

        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot(mapwin.Extents), MapWinGIS.Image)

        If image Is Nothing Then
            Return False
        End If


        Dim b As Boolean
        Dim cBack As GCallback
        b = image.Save(fName, False, MapWinGIS.ImageType.USE_FILE_EXTENSION, cBack)
        'image.Save(fName, MapWinGIS.ImageType.JPEG_FILE)
        Return b


    End Function

    Public Sub SaveImageFileByParam(ByVal fName As String, ByVal left As Double, ByVal right As Double, ByVal top As Double, ByVal bottom As Double, ByVal imgWidth As Integer)

        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot3(left, right, top, bottom, imgWidth), MapWinGIS.Image)

        If image Is Nothing Then
            Return
        End If

        image.Save(fName, MapWinGIS.ImageType.USE_FILE_EXTENSION)



        'Dim cvter As New MapWinUtility.ImageUtils
        'Dim img As Drawing.Image = cvter.IPictureDispToImage(CType(mapwin.SnapShot3(left, right, top, bottom, imgWidth), MapWinGIS.Image))

        'img.Save(fName, fType)

    End Sub

    Public Sub SaveImageFileByLayerExtent(ByVal fName As String, ByVal iHandle As Integer, ByVal zoom As Double, ByVal imgWidth As Integer)

        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot2(iHandle, zoom, imgWidth), MapWinGIS.Image)

        If image Is Nothing Then
            Return
        End If


        image.Save(fName, MapWinGIS.ImageType.USE_FILE_EXTENSION)

        'Dim cvter As New MapWinUtility.ImageUtils
        'Dim img As Drawing.Image = cvter.IPictureDispToImage(CType(mapwin.SnapShot2(iHandle, zoom, imgWidth), MapWinGIS.Image))

        'img.Save(fName, fType)

    End Sub

    Public Function GetLayersCopy() As Dictionary(Of String, Layer)

        Dim tReturn As New Dictionary(Of String, Layer)

        For Each kv As KeyValuePair(Of String, Layer) In m_LayerDic

            tReturn.Add(kv.Key, kv.Value)

        Next

        Return tReturn

    End Function

    Public Function GetExtens() As MapWinGIS.Extents

        Return mapwin.Extents



    End Function


    Public Function GetImageFromMap() As MapWinGIS.Image

        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot(mapwin.Extents), MapWinGIS.Image)

        Return image

    End Function

    Public Function GetImageFromMap(ByVal left As Double, ByVal right As Double, ByVal top As Double, ByVal bottom As Double, ByVal imgWidth As Integer) As MapWinGIS.Image

        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot3(left, right, top, bottom, imgWidth), MapWinGIS.Image)
        Return image

    End Function

    Public Function GetImageFromMap(ByVal iHandle As Integer, ByVal zoom As Double, ByVal imgWidth As Integer) As MapWinGIS.Image
        Dim image As New MapWinGIS.Image
        image = CType(mapwin.SnapShot2(iHandle, zoom, imgWidth), MapWinGIS.Image)

        Return image

    End Function


    Public Sub Redraw()

        mapwin.Redraw()

    End Sub




End Class
